
#include "GraphicsDevice.h"

#include "TextureCollection.h"
#include "SamplerStateCollection.h"
#include "RenderTargetBinding.h"
#include "GraphicsAdapter.h"

#include <System/Diagnostics/Debug.h>

#if Windows
// OpenGL + Windows includes.
//#include <windows.h>		// Header File For Windows
#include <gl\gl.h>			// Header File For The OpenGL32 Library
#include <gl\glu.h>			// Header File For The GLu32 Library
#include <gl\glaux.h>		// Header File For The Glaux Library
#else
#include <GLES/gl.h>
#include <GLES/glext.h>
#endif

using namespace Riccsson::Xna::Framework::Graphics;
using namespace Riccsson::Xna::Framework;

int GraphicsDevice::DeviceScreenWidth;
int GraphicsDevice::DeviceScreenHeight;

/*readonly*/ Color GraphicsDevice::DiscardColor = Color(68, 34, 136, 255);

#if OPENGL

void GraphicsDevice::SetVertexAttributeArray(Riccsson::System::Array<bool>* attrs)
{
	throw;
}

#endif

PROP3_GET_CPP(GraphicsDevice, bool, IsDisposed)
{
	throw;
}
		
PROP3_GET_CPP(GraphicsDevice, bool, IsContentLost)
{
	throw;
}

PROP3_GET_CPP(GraphicsDevice, bool, IsRenderTargetBound)
{
	throw;
}

PROP3_GET_CPP(GraphicsDevice, GC_PTR<TextureCollection>, Textures)
{
	throw;
}

PROP3_SET_CPP(GraphicsDevice, GC_PTR<TextureCollection>, Textures){throw;}

PROP3_GET_CPP(GraphicsDevice, GC_PTR<SamplerStateCollection>, SamplerStates)
{
	throw;
}

PROP3_SET_CPP(GraphicsDevice, GC_PTR<SamplerStateCollection>, SamplerStates){throw;}

GraphicsDevice::GraphicsDevice()
	: _blendState( BlendState::Opaque )
	, _depthStencilState( DepthStencilState::Default )
	, _rasterizerState( RasterizerState::CullCounterClockwise )
	, _vertexConstantBuffers( new ConstantBufferCollection(ShaderStage::Vertex, 16) )
	, _pixelConstantBuffers( new ConstantBufferCollection(ShaderStage::Pixel, 16) )
	, PROP3_INIT(GraphicsDevice, displayMode)
	, PROP3_INIT(GraphicsDevice, graphicsDeviceStatus)
	, PROP3_INIT(GraphicsDevice, viewport)
	, PROP3_INIT(GraphicsDevice, ScissorRectangle)
	, PROP3_INIT(GraphicsDevice, Textures)
	, PROP3_INIT(GraphicsDevice, SamplerStates)
	, PROP3_INIT(GraphicsDevice, depthStencilState)
	, PROP3_INIT(GraphicsDevice, blendState)
	, PROP3_INIT(GraphicsDevice, rasterizerState)
	, PROP3_INIT(GraphicsDevice, IsDisposed)
	, PROP3_INIT(GraphicsDevice, IsContentLost)
	, PROP3_INIT(GraphicsDevice, IsRenderTargetBound)
{
	_viewport.Width = Riccsson::Xna::Framework::Graphics::GraphicsDevice::DeviceScreenWidth;
	_viewport.Height = Riccsson::Xna::Framework::Graphics::GraphicsDevice::DeviceScreenHeight;
}

GraphicsDevice::~GraphicsDevice()
{

}

#if OPENGL
List<string> GraphicsDevice::GetGLExtensions()
{
	throw;
}
#endif // OPENGL

void GraphicsDevice::Initialize()
{

}

#if DIRECTX 

#if WINDOWS_PHONE

void GraphicsDevice::UpdateDevice(Device device, DeviceContext context)
{
	throw;
}

void GraphicsDevice::UpdateTarget(RenderTargetView renderTargetView)
{
	throw;
}

#elif WINDOWS_STOREAPP

/// <summary>
/// Creates resources not tied the active graphics device.
/// </summary>
void GraphicsDevice::CreateDeviceIndependentResources()
{
	throw;
}

/// <summary>
/// Create graphics device specific resources.
/// </summary>
void GraphicsDevice::CreateDeviceResources()
{
	throw;
}

void GraphicsDevice::CreateSizeDependentResources()
{
	throw;
}

#elif WINDOWS

/// <summary>
/// Create graphics device specific resources.
/// </summary>
void GraphicsDevice::CreateDeviceResources()
{
	throw;
}

void GraphicsDevice::CreateSizeDependentResources()
{
	throw;
}
		
#endif // WINDOWS

#endif // DIRECTX
		
PROP3_GET_CPP(GraphicsDevice, GC_PTR<RasterizerState>, rasterizerState)
{
	throw;
}

PROP3_SET_CPP(GraphicsDevice, GC_PTR<RasterizerState>, rasterizerState)
{
	throw;
}

PROP3_GET_CPP(GraphicsDevice, GC_PTR<BlendState>, blendState)
{
	throw;
}
PROP3_SET_CPP(GraphicsDevice, GC_PTR<BlendState>, blendState)
{
	throw;
}
		
PROP3_GET_CPP(GraphicsDevice, GC_PTR<DepthStencilState>, depthStencilState)
{
	throw;
}
PROP3_SET_CPP(GraphicsDevice, GC_PTR<DepthStencilState>, depthStencilState)
{
	throw;
}

void GraphicsDevice::Clear(Color color)
{
	glClearColor(color.R/255.0f, color.G/255.0f, color.B/255.0f, color.A/255.0f);
}

void GraphicsDevice::Clear(ClearOptions options, Color color, float depth, int stencil)
{
	throw;
}

void GraphicsDevice::Clear(ClearOptions options, Vector4 color, float depth, int stencil)
{
	throw;
}
		
void GraphicsDevice::Dispose()
{
	Dispose(true);
}

void GraphicsDevice::Dispose(bool disposing)
{

}

#if OPENGL
/// <summary>
/// Adds a dispose action to the list of pending dispose actions. These are executed at the end of each call to Present().
/// This allows GL resources to be disposed from other threads, such as the finalizer.
/// </summary>
/// <param name="disposeAction">The action to execute for the dispose.</param>
void GraphicsDevice::AddDisposeAction(Action disposeAction)
{
	throw;
}
#endif

void GraphicsDevice::Present()
{
	throw;
}

void GraphicsDevice::Present(Riccsson::System::Nullable<Riccsson::Xna::Framework::Rectangle> sourceRectangle, Riccsson::System::Nullable<Riccsson::Xna::Framework::Rectangle> destinationRectangle, Riccsson::System::IntPtr overrideWindowHandle)
{
	throw;
}

void GraphicsDevice::Reset()
{
	throw;
}

void GraphicsDevice::Reset(GC_PTR<PresentationParameters> presentationParameters)
{
	throw;
}

void GraphicsDevice::Reset(GC_PTR<PresentationParameters> presentationParameters, GC_PTR<GraphicsAdapter> graphicsAdapter)
{
	throw;
}

/// <summary>
/// Trigger the DeviceResetting event
/// Currently public: /*internal*/ to allow the various platforms to send the event at the appropriate time.
/// </summary>
void GraphicsDevice::OnDeviceResetting()
{
	throw;
}

/// <summary>
/// Trigger the DeviceReset event to allow games to be notified of a device reset.
/// Currently public: /*internal*/ to allow the various platforms to send the event at the appropriate time.
/// </summary>
void GraphicsDevice::OnDeviceReset()
{
	throw;
}
		
PROP3_GET_CPP(GraphicsDevice, GC_PTR<DisplayMode>, displayMode)
{
	throw;
}
PROP3_SET_CPP(GraphicsDevice, GC_PTR<DisplayMode>, displayMode){throw;}

PROP3_GET_CPP(GraphicsDevice, GraphicsDeviceStatus, graphicsDeviceStatus)
{
	throw;
}
PROP3_SET_CPP(GraphicsDevice, GraphicsDeviceStatus, graphicsDeviceStatus){throw;}

PROP3_GET_CPP(GraphicsDevice, Viewport, viewport)
{
	return _viewport;
}
PROP3_SET_CPP(GraphicsDevice, Viewport, viewport)
{
	throw;
}

PROP3_GET_CPP(GraphicsDevice, Riccsson::Xna::Framework::Rectangle, ScissorRectangle)
{
	throw;
}
PROP3_SET_CPP(GraphicsDevice, Riccsson::Xna::Framework::Rectangle, ScissorRectangle)
{
	throw;
}

void GraphicsDevice::SetRenderTarget(GC_PTR<RenderTarget2D> renderTarget)
{
	throw;
}
		
void GraphicsDevice::SetRenderTarget(GC_PTR<RenderTargetCube> renderTarget, CubeMapFace cubeMapFace)
{
	throw;
}
		
void GraphicsDevice::SetRenderTargets(Riccsson::System::Array<GC_PTR<RenderTargetBinding>>* renderTargets) 
{
	throw;
}

void GraphicsDevice::ApplyRenderTargets(Riccsson::System::Array<GC_PTR<RenderTargetBinding>>* renderTargets)
{
	throw;
}

#if WINRT
void GraphicsDevice::ResetRenderTargets()
{
	throw;        
}
#endif

GC_PTR<Riccsson::System::Array<GC_PTR<RenderTargetBinding>>> GraphicsDevice::GetRenderTargets()
{
	throw;
}

#if OPENGL

BeginMode GraphicsDevice::PrimitiveTypeGL(PrimitiveType primitiveType)
{
	throw;
}
		
#elif DIRECTX

PrimitiveTopology GraphicsDevice::ToPrimitiveTopology(PrimitiveType primitiveType)
{
	throw;
}
		
#endif


void GraphicsDevice::SetVertexBuffer(GC_PTR<VertexBuffer> vertexBuffer)
{
	throw;
}

void GraphicsDevice::SetIndexBuffer(GC_PTR<IndexBuffer> indexBuffer)
{
	throw;
}

PROP3_GET_CPP(GraphicsDevice, GC_PTR<IndexBuffer>, Indices)
{
	throw;
}
PROP3_SET_CPP(GraphicsDevice, GC_PTR<IndexBuffer>, Indices)
{
	throw;
}
PROP3_GET_CPP(GraphicsDevice, Shader, VertexShader)
{
	throw;
}
PROP3_SET_CPP(GraphicsDevice, Shader, VertexShader)
{
	throw;
}

PROP3_GET_CPP(GraphicsDevice, Shader, PixelShader)
{
	throw;
}
PROP3_SET_CPP(GraphicsDevice, Shader, PixelShader)
{
	throw;
}

void GraphicsDevice::SetConstantBuffer(ShaderStage* stage, int slot, GC_PTR<ConstantBuffer> buffer)
{
	throw;
}

#if OPENGL

/// <summary>
/// Activates the Current Vertex/Pixel shader pair into a program.         
/// </summary>
void GraphicsDevice::ActivateShaderProgram()
{
	throw;
}
#endif

void GraphicsDevice::ApplyState(bool applyShaders)
{
	throw;
}

#if DIRECTX

SharpDX.Direct3D11.InputLayout GraphicsDevice::GetInputLayout(Shader shader, VertexDeclaration decl)
{
	throw;
}

#endif

/// <summary>
/// Draw geometry by indexing into the vertex buffer.
/// </summary>
/// <param name="primitiveType">The type of primitives in the index buffer.</param>
/// <param name="baseVertex">Used to offset the vertex range indexed from the vertex buffer.</param>
/// <param name="minVertexIndex">A hint of the lowest vertex indexed relative to baseVertex.</param>
/// <param name="numVertices">An hint of the maximum vertex indexed.</param>
/// <param name="startIndex">The index within the index buffer to start drawing from.</param>
/// <param name="primitiveCount">The number of primitives to render from the index buffer.</param>
/// <remarks>Note that minVertexIndex and numVertices are unused in MonoGame and will be ignored.</remarks>
void GraphicsDevice::DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount)
{
	throw;
}


void GraphicsDevice::DrawPrimitives(PrimitiveType primitiveType, int vertexStart, int primitiveCount)
{
	throw;
}


#if PSM
PssVertexBuffer GraphicsDevice::GetVertexBuffer(VertexFormat[] vertexFormat, int requiredVertexLength, int requiredIndexLength)
{
	throw;
}
        
/// <summary>
/// Set the current _graphics VertexBuffer based on _vertexBuffer and _indexBuffer, reusing an existing VertexBuffer if possible
/// </summary>
void GraphicsDevice::BindVertexBuffer(bool bindIndexBuffer)
{
	throw;
}
#endif

int GraphicsDevice::GetElementCountArray(PrimitiveType primitiveType, int primitiveCount)
{
	throw;
}